#define EPSILON 1e-12

class AnaUtils
{
 public:
  enum TYPEID{
    kPROTON,
    kPION,
    kKAON,
    kELECTRON
  };

  static void EtaIni();
  static Double_t Eta0(){return extEta0(fkETA);}
  static Double_t Eta1(){return extEta1(fkETA);}

  static Double_t Mproton   (){ return  0.938272;}
  static Double_t Mpion     (){ return  0.139570;}
  static Double_t Mkaon     (){ return  0.493677;}
  static Double_t Melectron (){ return  5.109989e-04;}

  static Double_t Mass(const Int_t id);
  static Double_t FractionEtaCorrection(const Int_t itype, const Double_t ptmean, const Double_t maxeta);
  static Double_t RatioEtaCorrection(const Int_t itype, const Double_t ptmean);

 private:
  static Double_t extEta0(const Int_t keta){return keta*0.2;}
  static Double_t extEta1(const Int_t keta){const Double_t ffeta[]={0.2,0.4,0.6,0.9}; return ffeta[keta];}

  static Int_t fkETA;
};

Int_t AnaUtils::fkETA=-999;


void AnaUtils::EtaIni()
{
  TString pwd = gSystem->pwd();
  pwd.ToUpper();

  //================== fkETA                                                                                                                            
  if(pwd.Contains("ETA0"))
    fkETA = 0;
  else  if(pwd.Contains("ETA1"))
    fkETA = 1;
  else  if(pwd.Contains("ETA2"))
    fkETA = 2;
  else  if(pwd.Contains("ETA3"))
    fkETA = 3;
  else if(pwd.Contains("ETAALL"))
    fkETA=100;
  else{
    printf("AnaUtils::EtaIni wrong eta!! %s\n", pwd.Data());
    //exit(1);                                                                                                                                         
  }
}



Double_t AnaUtils::FractionEtaCorrection(const Int_t itype, const Double_t ptmean, const Double_t maxeta)
{
  //dividing dn is necessary!
  //fraction independent of eta width!
  //maxeta needs to be tuned by MC!!!

  const Double_t dy    = XGLUtils::DeltaY(Mass(itype), ptmean, Eta0(), Eta1()) / (Eta1()-Eta0());

  const Double_t bigdy = XGLUtils::DeltaY(Mass(itype), ptmean, extEta0(0), maxeta) / (maxeta-extEta0(0));

  return bigdy/dy;
}


Double_t AnaUtils::RatioEtaCorrection(const Int_t itype, const Double_t ptmean)
{
  //
  //eta correction for yield ratio of Nitype/Npion, should correct N -> N/dy
  //

  const Double_t dypion = XGLUtils::DeltaY(Mass(kPION), ptmean, Eta0(), Eta1());
  const Double_t dytype = XGLUtils::DeltaY(Mass(itype), ptmean, Eta0(), Eta1());
  if(dytype<EPSILON){
    printf("AnaUtils::RatioEtaCorrection dytype<eps ! %d %e %e %e %e\n", itype, ptmean, Eta0(), Eta1(), dytype);exit(1);
  }
  return dypion/dytype;
}

Double_t AnaUtils::Mass(const Int_t id)
{
  switch(id){
  case kPROTON:
    return Mproton();
  case kPION:
    return Mpion();
  case kKAON:
    return Mkaon();
  case kELECTRON:
    return Melectron();
  default:
    printf("AnaUtils::Mass wrong id %d\n", id); exit(1);
  }

  return -999;
}

